package com.yfp.device.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.NumberUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yfp.device.domain.DeviceCurrentComboStock;
import com.yfp.device.domain.dto.OrderCreateDTO;
import com.yfp.device.domain.vo.ForeshowVo;
import com.yfp.device.mapper.DeviceCurrentComboPlanStockMapper;
import com.yfp.device.service.DeviceCurrentComboStockService;
import com.yfp.device.service.DeviceServer;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author admin
 * @description 针对表【device_current_combo_stock】的数据库操作Service实现
 * @createDate 2024-06-20 11:04:22
 */
@Service
public class DeviceCurrentComboStockServiceImpl extends ServiceImpl<DeviceCurrentComboPlanStockMapper, DeviceCurrentComboStock> implements DeviceCurrentComboStockService {

    @Resource
    private DeviceCurrentComboPlanStockMapper deviceCurrentComboPlanStockMapper;

    @Resource
    private DeviceServer deviceServer;

    @Override
    public List<DeviceCurrentComboStock> getByMachineId(String machineId) {
        return deviceCurrentComboPlanStockMapper.getByMachineId(machineId);
    }

    @Override
    public List<ForeshowVo> deviceComboForecast(String machineId, Timestamp creatTime) {
        return deviceCurrentComboPlanStockMapper.deviceComboForecast(machineId,creatTime);
    }

    @Override
    public void insertAll(List<DeviceCurrentComboStock> dccsList) {
        deviceCurrentComboPlanStockMapper.insertAll(dccsList);
    }

    @Override
    public void batchUpdate(ArrayList<DeviceCurrentComboStock> dccsList) {
        deviceCurrentComboPlanStockMapper.batchUpdate(dccsList);
    }

    /**
     * 检测库存是否充足
     *
     * @param comboList
     * @param machineId
     * @return
     */
    @Override
    public Boolean checkStockAvailability(List<OrderCreateDTO.ShopCart> comboList, String machineId) {
        List<String> packageIds = comboList.stream().map(OrderCreateDTO.ShopCart::getComboId).collect(Collectors.toList());
        List<DeviceCurrentComboStock> deviceCurrentComboStocks = deviceCurrentComboPlanStockMapper.listByPackageIdsAndMachineId(packageIds, machineId);
        if (!NumberUtil.equals(CollUtil.size(packageIds), CollUtil.size(deviceCurrentComboStocks))) {
            return false;
        }

        for (OrderCreateDTO.ShopCart shoppingCart : comboList) {
            for (DeviceCurrentComboStock deviceCurrentComboStock : deviceCurrentComboStocks) {
                if (shoppingCart.getComboId().equals(deviceCurrentComboStock.getComboId())) {
                    if (shoppingCart.getCount() > Optional.ofNullable(deviceCurrentComboStock.getComboNum()).orElse(0)) {
                        return false;
                    }
                }
            }
        }
        return true;
    }

    /**
     * 减少库存
     *
     * @param comboList
     * @param machineId
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void decreaseStockQuantity(List<OrderCreateDTO.ShopCart> comboList, String machineId) {
        List<String> packageIds = comboList.stream().map(OrderCreateDTO.ShopCart::getComboId).collect(Collectors.toList());
        List<DeviceCurrentComboStock> deviceCurrentComboStocks = deviceCurrentComboPlanStockMapper.listByPackageIdsAndMachineId(packageIds, machineId);
        Map<String, DeviceCurrentComboStock> stockMapByPackageId = deviceCurrentComboStocks.stream().collect(Collectors.toMap(DeviceCurrentComboStock::getComboId, item -> item));

        Map<String, Integer> shoppingMapByPackageId = comboList.stream().collect(Collectors.groupingBy(OrderCreateDTO.ShopCart::getComboId, Collectors.summingInt(OrderCreateDTO.ShopCart::getCount)));
        List<DeviceCurrentComboStock> newStocks = shoppingMapByPackageId.entrySet().stream().map(entry -> {
            String packageId = entry.getKey();
            Integer quantity = entry.getValue();
            if (!stockMapByPackageId.containsKey(packageId)) {
                throw new RuntimeException("库存不足");
            }
            DeviceCurrentComboStock deviceCurrentComboStock = stockMapByPackageId.get(packageId);
            if (deviceCurrentComboStock.getComboNum() < quantity) {
                throw new RuntimeException("库存不足");
            }
            deviceCurrentComboStock.setComboNum(deviceCurrentComboStock.getComboNum() - quantity);
            return deviceCurrentComboStock;
        }).collect(Collectors.toList());

        this.updateBatchById(newStocks);

        // 将库存信息发送到设备
        deviceServer.sendStockInfo(machineId, newStocks);
    }

    /**
     * 获取线上库存信息
     * @param machineId
     * @return
     */
    @Override
    public List<DeviceCurrentComboStock> getByMacineId(String machineId) {
        return deviceCurrentComboPlanStockMapper.getByMacineId(machineId);
    }
}




